package com.tongzhan.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.Md5Utils;
import com.tongzhan.base.PageInfo;
import com.tongzhan.base.Return;
import com.tongzhan.data.vo.*;
import com.tongzhan.entity.User;
import com.tongzhan.entity.religion.*;
import com.tongzhan.repository.UserRepository;
import com.tongzhan.repository.religion.*;
import com.tongzhan.service.UserService;
import com.tongzhan.utils.JwtUtil;
import com.tongzhan.utils.RegexUtil;
import com.tongzhan.utils.SnowFlakeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private StreetRepository streetRepository;

    @Autowired
    private VillageRepository villageRepository;

    @Autowired
    private SiteRepository siteRepository;

    @Autowired
    private ReligionRepository religionRepository;

    @Autowired
    private ModuleSignRepository signRepository;

    @Autowired
    private SiteInfoRepository siteInfoRepository;

    @Override
    public Return addUser(User user) {
        User judgeUser
                = userRepository.findOne(new Query().addCriteria(Criteria.where("UserName").is(user.getUserName())
                .and("IsDelete").is(0)));
        if (judgeUser != null) {
            return new Return(Return.FAIL, "该用户名已被注册");
        }
        //用户对应模块标识
        ModuleSign moduleSign = new ModuleSign();
        moduleSign.setDutiesCode(user.getDutiesCode());
        //生成雪花Id
        SnowFlakeUtils snow = new SnowFlakeUtils(4, 1);
        user.setUserId(String.valueOf(snow.nextId()));
        moduleSign.setUserId(user.getUserId());
        //默认密码 123456，md5加密后大写
        String passWord = Md5Utils.getMD5("123456".getBytes());
        user.setPassWord(passWord);
        if (user.getStreetCode() != null) {
            //街道信息
            Street street = streetRepository.findByPrimaryKey(user.getStreetCode());
            if (street != null) {
                user.setStreetName(street.getStreetName());
                moduleSign.setStreetCode(street.getStreetCode());
            }
        }
        if (user.getVillageCode() != null) {
            //村社区信息
            Village village = villageRepository.findByPrimaryKey(user.getVillageCode());
            if (village != null) {
                user.setVillageName(village.getVillageName());
                moduleSign.setVillageCode(village.getVillageCode());
            }
        }
        if (user.getSiteCode() != null) {
            //场所信息
            Site site = siteRepository.findByPrimaryKey(user.getSiteCode());
            if (site != null) {
                user.setSiteName(site.getSiteName());
                user.setReligionCode(site.getReligionCode());
                user.setReligionName(site.getReligionName());
                moduleSign.setSiteCode(site.getSiteCode());
            }
        }
        if (user.getReligionCode() != null) {
            //宗教信息
            Religion religion = religionRepository.findByPrimaryKey(user.getReligionCode());
            if (religion != null) {
                user.setReligionName(religion.getReligionName());
                moduleSign.setReligionCode(religion.getReligionCode());
            }
        }
        //type为4 宗教用户
        user.setType(4);
        user.setIsDelete(0);
        user.setCreateTime(LocalDateTime.now());
        try {
            userRepository.insert(user);
            //模块标识数据
            moduleSign.setActivity(0L);
            moduleSign.setBill(0L);
            moduleSign.setLaw(0L);
            moduleSign.setLeave(0L);
            moduleSign.setNotify(0L);
            moduleSign.setPowerCheck(0L);
            moduleSign.setSafeCheck(0L);
            moduleSign.setFireCheck(0L);
            moduleSign.setUsual(0L);
            moduleSign.setCondition(0L);
            moduleSign.setCreateTime(LocalDateTime.now());
            signRepository.insert(moduleSign);
        } catch (Exception e) {
            return new Return(Return.EXEXCEPTION, "新增用户失败");
        }
        return new Return(Return.SUCCESS, "操作成功");
    }

    @Override
    public Return editUser(User user) {
        String userId = user.getUserId();
        User u = userRepository.findOne(new Query().addCriteria(Criteria.where("userId").is(userId)));
        user.setCreateTime(u.getCreateTime());
        User judgeUser
                = userRepository.findOne(new Query().addCriteria(Criteria.where("UserName").is(user.getUserName())
                .and("IsDelete").is(0).and("userId").nin(userId)));
        if (judgeUser != null) {
            return new Return(Return.FAIL, "该用户名已被注册");
        }
        //用户对应模块标识
        ModuleSign moduleSign = new ModuleSign();
        moduleSign.setDutiesCode(user.getDutiesCode());
        //生成雪花Id
        moduleSign.setUserId(userId);

        if (user.getStreetCode() != null) {
            //街道信息
            Street street = streetRepository.findByPrimaryKey(user.getStreetCode());
            if (street != null) {
                user.setStreetName(street.getStreetName());
                moduleSign.setStreetCode(street.getStreetCode());
            }
        }
        if (user.getVillageCode() != null) {
            //村社区信息
            Village village = villageRepository.findByPrimaryKey(user.getVillageCode());
            if (village != null) {
                user.setVillageName(village.getVillageName());
                moduleSign.setVillageCode(village.getVillageCode());
            }
        }
        if (user.getSiteCode() != null) {
            //场所信息
            Site site = siteRepository.findByPrimaryKey(user.getSiteCode());
            if (site != null) {
                user.setSiteName(site.getSiteName());
                user.setReligionCode(site.getReligionCode());
                user.setReligionName(site.getReligionName());
                moduleSign.setSiteCode(site.getSiteCode());
            }
        }
        if (user.getReligionCode() != null) {
            //宗教信息
            Religion religion = religionRepository.findByPrimaryKey(user.getReligionCode());
            if (religion != null) {
                user.setReligionName(religion.getReligionName());
                moduleSign.setReligionCode(religion.getReligionCode());
            }
        }
        //type为4 宗教用户
        user.setType(4);
        user.setIsDelete(0);
        try {
            user.setUpdateTime(LocalDateTime.now());
            userRepository.updateByPrimaryKeySelective(user);
            //模块标识数据
            moduleSign.setActivity(0L);
            moduleSign.setBill(0L);
            moduleSign.setLaw(0L);
            moduleSign.setLeave(0L);
            moduleSign.setNotify(0L);
            moduleSign.setPowerCheck(0L);
            moduleSign.setSafeCheck(0L);
            moduleSign.setFireCheck(0L);
            moduleSign.setUsual(0L);
            moduleSign.setCondition(0L);
            moduleSign.setCreateTime(LocalDateTime.now());
            signRepository.updateByPrimaryKey(moduleSign);
        } catch (Exception e) {
            return new Return(Return.EXEXCEPTION, "编辑用户失败");
        }
        return new Return(Return.SUCCESS, "操作成功");
    }

    @Override
    public Return changePassword(String userId, String oldPassword, String newPassword) {
        User user = userRepository.findByPrimaryKey(userId);
        if (user != null) {
            String password = user.getPassWord();
            if (!password.equals(oldPassword)) {
                return new Return(Return.FAIL, "旧密码不正确");
            }
            if (newPassword.equals(oldPassword)) {
                return new Return(Return.FAIL, "新密码不能与旧密码相同！");
            }
            user.setPassWord(newPassword);
            user.setUpdateTime(LocalDateTime.now());
            long res = userRepository.updateByPrimaryKey(user);
            if (res < 0) {
                return new Return(Return.FAIL, "修改密码失败");
            }
        }
        return new Return(Return.SUCCESS, "操作成功");
    }

    @Override
    public Return editUserInfo(String userId, String realName, String telephone) {
        //校验手机号码
        boolean flag = RegexUtil.validPhoneNum("0", telephone);
        if (!flag) {
            return new Return(Return.FAIL, "手机号格式不正确");
        }
        User user = userRepository.findByPrimaryKey(userId);
        user.setRealName(realName);
        user.setTelephone(telephone);
        user.setUpdateTime(LocalDateTime.now());
        long res = userRepository.updateByPrimaryKey(user);
        if (res < 0) {
            return new Return(Return.FAIL, "修改失败");
        }
        return new Return(Return.SUCCESS, "操作成功");
    }

    @Override
    public Return getUserList(String dutiesCode, String realName, Integer page, Integer size) {
        //查询条件
        Query query = new Query();
        query.addCriteria(Criteria.where("Type").is(4));
        query.addCriteria(Criteria.where("IsDelete").is(0));
        if (StringUtils.isNotEmpty(dutiesCode)) {
            query.addCriteria(Criteria.where("DutiesCode").is(dutiesCode));
        }
        if (StringUtils.isNotEmpty(realName)) {
            query.addCriteria(Criteria.where("RealName").regex(".*?" + realName + ".*"));
        }
        //宗教场所
        if ("04".equals(dutiesCode)) {
            query.with(Sort.by(Sort.Direction.ASC, "ReligionCode"));
        } else {
            query.with(Sort.by(Sort.Direction.DESC, "CreateTime"));
        }
        //分页查询
        Page<User> pageList = userRepository.findPage(query, PageRequest.of(page - 1, size));
        //分页信息
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPage(page);
        pageInfo.setSize(pageList.getContent().size());
        pageInfo.setTotal(pageList.getTotalElements());
        //封装返回数据
        Map<String, Object> map = new HashMap<>();
        List<UserVO> vos = new ArrayList<>();
        //分页后的用户列表
        List<User> userList = pageList.getContent();
        if (!CollectionUtils.isEmpty(userList)) {
            vos = userList.stream().map(c -> {
                UserVO vo = new UserVO();
                vo.setHeadPortrait(c.getPicture());
                BeanUtils.copyProperties(c, vo);
                return vo;
            }).collect(Collectors.toList());
        }
        map.put("userList", vos);
        map.put("pageInfo", pageInfo);
        return new Return(map);
    }

    @Override
    public User selectByUserId(String userId) {
        return userRepository.findByPrimaryKey(userId);
    }

    @Override
    public Return login(HttpServletResponse response, String username, String password) {
        //查询条件
        Query query = new Query();
        query.addCriteria(Criteria.where("IsDelete").is(0)
                .and("UserName").is(username)
                .and("PassWord").is(password));
//        query.addCriteria(Criteria.where("Type").is(4)
//                .and("IsDelete").is(0)
//                .and("UserName").is(username)
//                .and("PassWord").is(password));
        User user = userRepository.findOne(query);
        if (user == null) {
            return new Return(Return.FAIL, "用户名或密码错误");
        }
        //允许统战部、党派工商科、镇街道、社区、基层大统战、侨务工作科、民宗局能访问
        Integer type = user.getType();
        if (type != 4) {
            String dutiesCode = user.getDutiesCode();
            if (!dutiesCode.equals("00")
                    && !dutiesCode.equals("01")
                    && !dutiesCode.equals("11")
                    && !dutiesCode.equals("21")
                    && !dutiesCode.equals("31")
                    && !dutiesCode.equals("z1")
                    && !dutiesCode.equals("t1")
                    && !dutiesCode.equals("c1")) {
                return new Return(Return.FAIL, "用户名或密码错误");
            }
        }
        //VO
        UserVO vo = new UserVO();
        BeanUtils.copyProperties(user, vo);
        //封装返回数据
        Map<String, Object> map = new HashMap<>();
        map.put("userInfo", vo);
        //基于工具类生成jwt令牌
        String token = JwtUtil.createJWT(UUID.randomUUID().toString(), JSON.toJSONString(user), null);
        map.put("token", token);
        //将token放在响应头
        response.setHeader(JwtUtil.AUTH_HEADER_KEY, token);
        return new Return(map);
    }

    @Override
    public User selectUserBySiteCode(String siteCode) {
        return userRepository.findOne(new Query().addCriteria(Criteria.where("SiteCode").is(siteCode).and("IsDelete").is(0)));
    }

    @Override
    public List<User> selectUnReport(List<String> codes, String dutiesCode) {
        //查询条件
        Query query = new Query();
        query.addCriteria(Criteria.where("DutiesCode").is(dutiesCode));
        if (!CollectionUtils.isEmpty(codes)) {
            //宗教团体
            if ("03".equals(dutiesCode)) {
                query.addCriteria(Criteria.where("ReligionCode").nin(codes));
            }
            //宗教场所、民间信仰点
            if ("04".equals(dutiesCode) || "07".equals(dutiesCode)) {
                query.addCriteria(Criteria.where("SiteCode").nin(codes));
            }
        }
        return userRepository.findAll(query);
    }

    @Override
    public void signReminder(List<User> users) {
        if (!CollectionUtils.isEmpty(users)) {
            for (User user : users) {
                ModuleSign sign = signRepository.findByPrimaryKey(user.getUserId());
                if (sign != null) {
                    sign.setBill(sign.getBill() + 1);
                    signRepository.updateByPrimaryKey(sign);
                    log.info(LocalDate.now().toString() + "--" + user.getUserName() + " 未上报财务信息，角标提醒");
                }
            }
        }
    }

    @Override
    public Return getUserSign(String userId) {
        ModuleSign sign = signRepository.findByPrimaryKey(userId);
        //VO
        ModuleSignVO vo = new ModuleSignVO();
        if (sign != null) {
            BeanUtils.copyProperties(sign, vo);
        }
        return new Return(vo);
    }

    @Override
    public Return deleteUser(String userId) {
        User user = userRepository.findByPrimaryKey(userId);
        if (user == null) {
            return new Return(Return.FAIL, "用户不存在");
        }
        user.setIsDelete(1);
        userRepository.updateByPrimaryKey(user);
        return new Return(Return.SUCCESS, "删除成功");
    }

    @Override
    public Return getCount() {
        //查询佛教数量
        List<Site> buddhismList = siteRepository.findAll(new Query().addCriteria(Criteria.where("ReligionCode").is("01")));
        //查询道教数量
        List<Site> taoismList = siteRepository.findAll(new Query().addCriteria(Criteria.where("ReligionCode").is("02")));
        //查询基督教数量
        List<Site> christianityList = siteRepository.findAll(new Query().addCriteria(Criteria.where("ReligionCode").is("03")));
        //查询民间信仰点数量
        List<SiteInfo> beliefPointList = siteInfoRepository.findAll(new Query().addCriteria(Criteria.where("Type").is(1)));
        //VO
        ReligionCountVO vo = new ReligionCountVO();
        vo.setBuddhism(buddhismList.size());
        vo.setTaoism(taoismList.size());
        vo.setChristianity(christianityList.size());
        vo.setBeliefPoint(beliefPointList.size());
        return new Return(vo);
    }

    @Override
    public Return getSiteInfo(String userId) {
        User user = userRepository.findByPrimaryKey(userId);
        if (user == null) {
            return new Return(Return.FAIL, "用户不存在");
        }
        Map<String, Object> map = new HashMap<>();
        StreetVO streetVO = new StreetVO();
        streetVO.setStreetCode(user.getStreetCode());
        streetVO.setStreetName(user.getStreetName());
        map.put("street", streetVO);
        VillageVO villageVO = new VillageVO();
        villageVO.setVillageCode(user.getVillageCode());
        villageVO.setVillageName(user.getVillageName());
        map.put("village", villageVO);
        SiteVO siteVO = new SiteVO();
        siteVO.setSiteCode(user.getSiteCode());
        siteVO.setSiteName(user.getSiteName());
        map.put("site", siteVO);
        return new Return(map);
    }

    @Override
    public Return getUserInfo(String userId) {
        User user = userRepository.findByPrimaryKey(userId);
        if (user == null) {
            return new Return(Return.FAIL, "用户不存在");
        }
        return new Return(user);
    }

    @Override
    public void resetPassword(String userId) {
        User user = userRepository.findByPrimaryKey(userId);
        if (user != null) {
            user.setPassWord(Md5Utils.getMD5("123456".getBytes()));
            user.setUpdateTime(LocalDateTime.now());
            userRepository.updateByPrimaryKey(user);
        }
    }
}
